package com.ps.bicyclecharging.service.impl;


import com.ps.bicyclecharging.mapper.ChargingMapper;
import com.ps.bicyclecharging.service.BicycleService;
import com.ps.bicyclecharging.service.ChargingService;
import com.ps.domain.*;
import com.ps.dto.Pay;
import com.ps.enums.ErrorCode;
import com.ps.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author:Lisa
 * @create:2019/08/13
 */
@Service
public class ChargingServiceImpl implements ChargingService {

    @Autowired
    private ChargingMapper chargingMapper;

    @Autowired
    private BicycleService bicycleService;



    /**
     * 联系客服
     */
    @Override
    public void contactCustomerService() {

    }

    /**
     * 上报计费异常
     * @param breakdown
     */
    @Override
    public void billingExceptions(Breakdown breakdown) {

        //如果传过来的数据为空 或者单车编号《=0，那就抛出异常提示数据异常
        this.throwDataException( breakdown == null || breakdown.getBid()<=0 );

//        校验用户id、单车id是否存在，不存在则抛数据异常   （此处需要调用单车系统的接口、用户系统的接口）
        Account account = this.checkAccountByUid(breakdown.getUid());

        Bicycle bicycle = bicycleService.queryBicycleById(breakdown.getBid());
        this.throwDataException(bicycle == null);

        // 调用单车系统新增故障记录
        bicycleService.billingexceptions(breakdown);
    }

    /**
     * 查询余额
     * @param uid
     * @return
     */
    @Override
    public double queryBalanceByUid(long uid) {
        Account account = this.checkAccountByUid(uid);

        return account.getBalance();
    }


    /**
     * 查询充值记录
     * @Param id 用户id
     *      state 状态 1.查支付记录，2.查充值记录，3.全部流水
     */
    @Override
    public List<Recharge> queryRechargeRecords(long id, String state) {
        this.throwDataException( id<=0 || state==null);

        List<Recharge> list = null;

        if("1".equals(state)){//查支付记录

            list = chargingMapper.queryPayRecords(id);
        }else if("2".equals(state)){//查充值记录

            list = chargingMapper.queryRecharges(id);
        }else if("3".equals(state)){//全部流水

            list = chargingMapper.queryAllRechargesByUid(id);
        }

        if(list.size() == 0){
            throw new BusinessException(ErrorCode.NO_DATA);
        }

        return list;
    }


    /**
     * 查询押金
     * @Param id 用户id
     */
    @Override
    public double queryDeposit(long id) {
        Account account = this.checkAccountByUid(id);

        return account.getDeposit();
    }


    /**
     * 设置免密支付
     * @Param id 用户id
     * @Param password 用户支付密码
     */
    @Override
    public void densityFree(long id, String password) {
        this.throwDataException(password == null);

        Account account = this.checkAccountByUid( id );

        // 支付密码不正确
        if(!password.equals(account.getPassword())){
            throw new BusinessException(ErrorCode.PAYMENT_PASSWORD_IS_ABNORMAL);
        }

        chargingMapper.densityFree(id, "1");
    }


    /**
     * 申请退还押金
     * @Param id 用户id
     */
    @Override
    public void returnDeposit(long id) {
        Account account = this.checkAccountByUid( id );

//        将押金设为0
        chargingMapper.updateDeposit(id, 0);

//        查询用户之前充值押金时的方式
        List<Recharge> list = chargingMapper.queryRechargeRecords(id,"2");
        Recharge beforeRecharge = list.get(0);

//        调用三方，退还押金给用户

//        生成押金退还流水
        Recharge recharge = new Recharge(account.getId(), 0-account.getDeposit(),
                beforeRecharge.getPayMethod(), "4","2");

        chargingMapper.addRecharge(recharge);
    }


    /**
     * 查询计费规则
     */
    @Override
    public String queryBillingRules() {
        String billingPlan = "0";
        Config config = chargingMapper.queryConfigByBillingPlane(billingPlan);
        return config.getRemark();
    }

    /**
     * 设置支付密码
     *      传入参数uid、password
     * @return
     */
    @Override
    public void setPaymentPsw(long uid,String password) {
        Account account = this.checkAccountByUid( uid );

        chargingMapper.updatePayPswByUid(uid, password);

    }

    /**
     * 修改支付密码
     *      传入参数uid、password、newPassword
     * @return
     */
    @Override
    public void updatePaymentPsw(long uid, String password, String newPassword) {
        this.throwDataException( password==null || newPassword==null);

        Account account = this.checkAccountByUid( uid );

//        原支付密码不正确
        if(!password.equals(account.getPassword())){
            throw new BusinessException(ErrorCode.BEFORE_PAY_PASSWORD_ERROR);
        }

        chargingMapper.updatePayPswByUid(uid, password);
    }

    /**
     * 充值接口
     * @param recharge
     */
    @Override
    public void recharge(Recharge recharge) {
        this.throwDataException( recharge == null );

        Account account = this.checkAccountById(recharge.getAid());

//        修改账户余额  +钱
        chargingMapper.updateBalance(recharge.getAid(), recharge.getMoney());

//        新增流水（充值记录)
        chargingMapper.addRecharge(recharge);
    }


    /**
     * 支付
     */
    @Override
    public void pay(Pay pay) {
//        金额的值不能是小于等于0的
        if(pay.getMoney() <= 0){
            throw new BusinessException(ErrorCode.MONEY_LESS_THAN_ZERO);
        }

        Account account = this.checkAccountByUid( pay.getUid() );


//        没有传支付密码过来的
        if(pay.getPassword() == null){

//            免密支付
            this.noPasswordPay(pay,account);
        }else{

//            用支付密码支付
            this.passwordPay(pay,account);
        }
    }




    /**
     * 免密支付
     */
    private void noPasswordPay(Pay pay, Account account) {
//        并没有设置免密支付
        if("2".equals(account.getType())){
            throw new BusinessException(ErrorCode.NEED_PASSWORD);
        }

        this.payMoney(pay,account);
    }

    /**
     * 用支付密码支付
     */
    private void passwordPay(Pay pay, Account account) {
//        还未设置支付密码
        if(account.getPassword() == null){
            throw new BusinessException(ErrorCode.NEED_SET_PASSWORD);
        }

//        支付密码不正确
        if(!account.getPassword().equals(pay.getPassword())){
            throw new BusinessException(ErrorCode.ERROR_PAY_PASSWORD);
        }

        this.payMoney(pay,account);
    }


    private void payMoney(Pay pay, Account account){
//        修改账户余额
        chargingMapper.updateBalance(pay.getUid(), 0 - pay.getMoney());

//        增加流水
        Recharge recharge = new Recharge(account.getId(), 0-pay.getMoney(),
                pay.getPayMethod(), pay.getType(),"2");

        chargingMapper.addRecharge(recharge);
    }

    /**
     *  根据用户id查用户账户信息，如果用户信息不存在则直接抛异常到前台
     */
    private Account checkAccountByUid(long uid){
        this.throwDataException( uid <= 0 );

        Account account = chargingMapper.queryAccountByUid( uid );

        this.throwDataException(account==null);

        return account;
    }

    /**
     *  根据账户id查用户账户信息，如果用户信息不存在则直接抛异常到前台
     */
    private Account checkAccountById(long id){
        this.throwDataException( id <= 0 );

        Account account = chargingMapper.queryAccountById( id );

        this.throwDataException(account==null);

        return account;
    }

    /**
     * 抛数据异常
     */
    private void throwDataException(boolean bool){
        if(bool){
            throw new BusinessException(ErrorCode.ERROR_EXCEPTION_DATA);
        }
    }

}
